/**
 * 
 * @param state
 * @returns
 */
function Block(initialState) {
	this.state = initialState;
	this.state.initPos = this.position;
}

Block.prototype.getPosition = function() {
	return this.state.position;
};

Block.prototype.move = function(direction) {
	var canMove = this.canMove(direction);
	if (canMove) {
		this.state.position += direction;
	}

	return canMove;
};

Block.prototype.canMove = function(direction) {
	return (this.state.position + direction >= this.state.min) && (this.state.position + direction <= this.state.max);
};

Block.prototype.isWinPosition = function() {
	return (this.state.position == this.state.winPosition);
};

/**
 * 
 * @param view
 * @returns
 */
function LockController(view) {
	this.view = view;
	this.initBlocks();
	this.moveCount = 0;
}

LockController.prototype.initBlocks = function() {
	this.blocks = [];
	this.blocks[0] = new Block({
		position : 1,
		min : 0,
		max : 2,
		winPosition : 0
	});
	this.blocks[1] = new Block({
		position : 2,
		min : 1,
		max : 3,
		winPosition : 3
	});
	this.blocks[2] = new Block({
		position : 1,
		min : 1,
		max : 3,
		winPosition : 3
	});
};

LockController.prototype.startup = function() {
	this.view.init(this);
	this.updateButtonState();
	this.repaint();
};

LockController.prototype.repaint = function() {
	this.view.update(this.getBlocksPositions());
};

LockController.prototype.getBlocksPositions = function() {
	var positions = [];
	for ( var i = 0; i < this.blocks.length; i++) {
		positions.push(this.blocks[i].getPosition());
	}

	return positions;
};

LockController.prototype.indexInBounds = function(blockIndex) {
	return blockIndex >= 0 && blockIndex < this.blocks.length;
};

LockController.prototype.onMove = function(blockIndex, direction) {
	var moved = false;

	if (this.canMove() && !this.checkSolved()) {
		if (this.indexInBounds(blockIndex)) {
			moved = this.blocks[blockIndex].move(direction);
		}
		if (moved && this.indexInBounds(blockIndex - 1)) {
			this.blocks[blockIndex - 1].move(direction);
		}
		if (moved && this.indexInBounds(blockIndex + 1)) {
			this.blocks[blockIndex + 1].move(direction);
		}
	}

	this.updateButtonState();
	this.repaint();
	this.checkWinOrStale(moved);

	return moved;
};

LockController.prototype.updateButtonState = function() {
	var buttonsState = [];

	for ( var i = 0; i < this.blocks.length; i++) {
		var block = this.blocks[i];
		buttonsState.push(block.canMove(-1));
		buttonsState.push(block.canMove(+1));
	}

	this.view.updateButtons(buttonsState);
};

LockController.prototype.checkWinOrStale = function(moved) {
	if (!this.checkSolved()) {
		if (moved && this.moveCount >= 2) {
			this.onStale();
		}
		if (moved) {
			this.moveCount++;
		}
	} else {
		if (this.moveCount >= 3) {
			this.onStale();
		}
		this.moveCount++;
	}
};

LockController.prototype.onStale = function() {
	this.view.onStale();
};

LockController.prototype.canMove = function() {
	return this.moveCount <= 2;
};

LockController.prototype.checkSolved = function() {
	var solved = true;

	for ( var i = 0; i < this.blocks.length; i++) {
		var block = this.blocks[i];
		if (!block.isWinPosition()) {
			solved = false;
			break;
		}
	}

	return solved;
};

LockController.prototype.onOpenLock = function() {
	var solved = this.checkSolved();

	if (solved) {
		new AEnigmatesStorage("lock").solved();
		this.view.onSolved();
	}

	return solved;
};

LockController.prototype.reset = function() {
	this.moveCount = 0;
	this.initBlocks();
	this.view.onReset(this.getBlocksPositions());
	this.updateButtonState();
};